home *** CD-ROM | disk | FTP | other *** search
- /*
- * eh_sgl.c
- *
- * Practical Algorithms for Image Analysis
- *
- * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
- */
-
- /*
- * E(xtract) H(istograms)_SGL
- *
- * routine to extract desired set of parameters from a data file of
- * type .SGL whose name is entered as a command line argument and
- * construct a histogram; write output file of type *.hdt
- *
- */
- #include "eh_sgl.h"
-
- #define LINE_LEN 80 /* max length of line in data file */
- #define TITLE_LEN 30 /* max length of line title */
- #define FN_LEN 10 /* length of data file name */
-
- #define BIN_NUMBER 10 /* no bins in histogram */
- #define READ_SEGM 0
- #define READ_AREA 1
- #define READ_LEN 2
- #define READ_WIDTH 3
- #define READ_HAREA 4
- #define READ_QUOT 5
- #define SEGM_HIST "\nhistogram for SGL segment number"
- #define AREA_HIST "\nhistogram for polygon area"
- #define LEN_HIST "\nhistogram for polygon length"
- #define WIDTH_HIST "\nhistogram for polygon width"
- #define CH_AREA_HIST "\nhistogram for convex hull area"
- #define QUOT_HIST "\nhistogram for quotient of poly area and hull area"
-
- #define ON 1
- #define OFF 0
-
- #undef SHOW_SORT
-
- /*
- * ** global variables
- */
- extern char *optarg;
- extern int optind, opterr;
-
-
- static char *HIST_HEADER;
- int MAKE_HIST = -1;
- int N_BINS = BIN_NUMBER;
- int MIN_SET = 0;
- int MAX_SET = 0;
- int SAVE_VERT = 0; /* vertex coordinates stored in .sgl file */
- int WRITE_FILE = 0;
- int SHOW_INPUT = 1;
-
- /*
- * usage of routine
- */
- void
- usage (char *progname)
- {
- progname = last_bs (progname);
- printf ("USAGE: %s infile [-v] [-d] [-s] [-a] [-l] [-b] [-h] [-q]\n", progname);
- printf (" [-n n] [-i f] [-f f] [-w] [-L]\n");
- printf ("\n%s extracts histogram data from SGL output files created by xsgll\n\n", progname);
- printf ("ARGUMENTS:\n");
- printf (" infile: input filename (SGL)\n\n");
- printf ("OPTIONS:\n");
- printf (" -v: expect vertex coordinates in .sgl file\n");
- printf (" -d: disply input data\n\n");
- printf (" construct histogram for:\n");
- printf (" -s: segment number (per SGL)\n");
- printf (" -a: area\n");
- printf (" -l: length\n");
- printf (" -b: width\n");
- printf (" -h: (convex) hull area\n");
- printf (" -q: quotient area/conv hull area\n\n");
- printf (" -n n: set number of bins to n (default: 10)\n");
- printf (" -i f: set initial value to f(float)\n");
- printf (" -f f: set final value to f(float)\n");
- printf (" -w: write output file of type .hdt (hist data)\n");
- printf (" -L: print Software License for this module\n");
- exit (1);
- }
-
-
-
- /*
- * ** comparison function for qsort():
- * ** sort array of tuples in order of increassing x-values
- */
- int
- compare (t1, t2)
- float *t1, *t2;
- {
- return ((int) SIGN (*t1 - *t2));
- }
-
-
- /*
- * ** determine mean of input data set
- */
- double
- find_mean (float *data, int n)
- {
- int i;
- double mean = 0.0;
-
- for (i = 0; i < n; i++)
- mean += *(data + i);
-
- return (mean / (double) n);
- }
-
- /*
- * ** determine standard deviation of input data set
- */
- double
- find_sigma (float *data, int n, double mean)
- {
- int i;
- double xi, sigma = 0.0;
-
- for (i = 0; i < n; i++) {
- xi = (double) (*(data + i));
- sigma += (xi - mean) * (xi - mean);
- }
- sigma /= (double) (n - 1);
-
- return (sqrt (sigma));
- }
-
-
- /*
- * ** construct histogram of input data
- */
- void
- construct_hist (int n, float *data, float *hist, double bw, double data_base)
- {
- int i, ibin;
-
- for (i = 0; i < n; i++) {
- if (*(data + i) != 0) {
- ibin = 0;
- while (*(data + i) >= data_base + ibin * bw)
- ibin++;
- *(hist + ibin - 1) += 1;
- }
- }
- }
-
-
-
- /*
- * ** skip n lines
- */
- void
- skip_n_lines (FILE * file_pointer, int n_lines_to_skip)
- {
- int i;
- char ch;
-
- for (i = 0; i < n_lines_to_skip; i++) {
- while ((ch = getc (file_pointer)) != '\n');
- }
- }
-
-
-
- void
- main (argc, argv)
- int argc;
- char *argv[];
- {
- int i_arg;
- int i, ich, is;
- int i_sgl, n_sgl;
- int n_vertex;
- char colon, comma, equ, wspace, opar, cpar;
- static char wbuf[20];
- static char *inp_suffix =
- {".sgl"}; /* default inp file suffix */
- static char *sgl_type =
- {".sgl"}; /* suffix for .sgl inp file */
- static char *wsuffix =
- {".hdt"}; /* suffix for output file name */
- char *rbuf;
-
- static char *stop_code =
- {"histogram"};
- int stop_count = 9;
- int proc_flag;
-
- char buf[64];
- char line_title[TITLE_LEN], line_buf[LINE_LEN], fn_buf[13];
-
- int x_ctr, y_ctr;
- int area, h_area;
- float farea, fh_area;
- float len, width;
- int ns;
- float bin_width, min = (float) -1.0, max = (float) -1.0;
- float *data, *hist;
- double mean, std_dev;
- float foo = (float) 1.0;
- int n_parms = 3;
-
- FILE *fpIn, *fpOut;
-
- /*
- * ** cmd line options:
- */
- static char *optstring = "vdsalbhqn:i:f:wL";
-
-
- /*
- * ** parse command line
- */
- optind = 2;
- opterr = ON; /* give error messages */
-
-
- if (argc < 2)
- usage (argv[0]);
- while ((i_arg = getopt (argc, argv, optstring)) != EOF) {
- switch (i_arg) {
- case 'v':
- printf ("\n...option %c: ", i_arg);
- printf ("expect vertex coord in .sgl file\n");
- SAVE_VERT = ON;
- break;
- case 'd':
- printf ("\n...option %c: ", i_arg);
- printf ("display input data\n");
- SHOW_INPUT = ON;
- break;
- case 's':
- printf ("\n...option %c: ", i_arg);
- printf ("construct histogram for segment number\n");
- MAKE_HIST = READ_SEGM;
- HIST_HEADER = SEGM_HIST;
- break;
- case 'a':
- printf ("\n...option %c: ", i_arg);
- printf ("construct histogram for polygon area\n");
- MAKE_HIST = READ_AREA;
- HIST_HEADER = AREA_HIST;
- break;
- case 'l':
- printf ("\n...option %c: ", i_arg);
- printf ("construct histogram for polygon length\n");
- MAKE_HIST = READ_LEN;
- HIST_HEADER = LEN_HIST;
- break;
- case 'b':
- printf ("\n...option %c: ", i_arg);
- printf ("construct histogram for polygon width\n");
- MAKE_HIST = READ_WIDTH;
- HIST_HEADER = WIDTH_HIST;
- break;
- case 'h':
- printf ("\n...option %c: ", i_arg);
- printf ("construct histogram for conv hull area\n");
- MAKE_HIST = READ_HAREA;
- HIST_HEADER = CH_AREA_HIST;
- break;
- case 'q':
- printf ("\n...option %c: ", i_arg);
- printf ("construct histogram for area/ch_area\nn");
- MAKE_HIST = READ_QUOT;
- HIST_HEADER = QUOT_HIST;
- break;
- case 'n':
- printf ("\n...option %c: ", i_arg);
- printf ("set number of bins to %d\n",
- N_BINS = atoi (optarg));
- break;
- case 'i':
- printf ("\n...option %c: ", i_arg);
- printf ("set min (init value) to %f\n",
- min = (float) atof (optarg));
- MIN_SET = 1;
- break;
- case 'f':
- printf ("\n...option %c: ", i_arg);
- printf ("set max (final value) to %f\n",
- max = (float) atof (optarg));
- MAX_SET = 1;
- break;
- case 'w':
- printf ("\n...option %c: ", i_arg);
- printf ("write output to file %s\n", wbuf);
- WRITE_FILE = 1;
- break;
- case 'L':
- print_sos_lic ();
- exit (0);
- default:
- printf ("\n...unknown cmd line argument\n");
- exit (1);
- break;
- }
- }
-
- printf ("read sgl data from file %s\n",
- rbuf = argv[1]);
- if ((fpIn = fopen (rbuf, "r")) == NULL) {
- printf ("\n...cannot open input file %s\n", rbuf);
- exit (1);
- }
-
- /* construct output file name */
- ich = 0;
- while ((*(wbuf + ich) = *(rbuf + ich)) != '.')
- ich++;
- for (is = 0; is < 4; is++)
- *(wbuf + (ich) + is) = *(wsuffix + is);
- /* strip input file suffix */
- for (is = 0; is < 4; is++)
- *(inp_suffix + is) = *(rbuf + (ich) + is);
- if (strcmp (inp_suffix, sgl_type) != 0) {
- printf ("\n...unknown input file type encountered:");
- printf (" default: %s\n", sgl_type);
- fclose (fpIn);
- exit (1);
- }
-
- if (MAKE_HIST == -1) {
- printf ("\n...problem selecting input for histogram:");
- printf (" MAKE_HIST = %d\n", MAKE_HIST);
- printf ("...select suitable option: -a, -l, -b, -h, -q\n");
- exit (1);
- }
-
- /*
- * ** retrieve data from .sgl file
- */
- skip_n_lines (fpIn, 6);
- fgets (line_buf, LINE_LEN, fpIn);
- sscanf (line_buf, "%[^:]%c%s", buf, &colon, fn_buf);
- printf ("\n...data from input file %s\n", fn_buf);
-
- fgets (line_buf, LINE_LEN, fpIn);
- sscanf (line_buf, "%[^:]%c%d", buf, &colon, &n_sgl);
- printf ("total no segment clusters in this file: %d\n", n_sgl);
-
-
- /*
- * ** allocate memory for input data
- */
- if ((data = (float *) calloc ((size_t) n_sgl, sizeof (float))) == NULL) {
- printf ("\nEH_SGL: mem alloc for data failed\n");
- exit (1);
- }
-
- /*
- * ** scan input file
- */
- skip_n_lines (fpIn, 2);
-
- i_sgl = 0;
- proc_flag = 1;
- do {
- skip_n_lines (fpIn, 1);
- fgets (line_buf, LINE_LEN, fpIn);
- sscanf (line_buf, "%[^:]", line_title);
-
- if ((proc_flag = strncmp (line_title, stop_code, stop_count)) != 0) {
- fgets (line_buf, LINE_LEN, fpIn);
- sscanf (line_buf, "%[^:]%c%d", buf, &colon, &ns);
- fgets (line_buf, LINE_LEN, fpIn);
- sscanf (line_buf, "%[^=]%c%d", buf, &equ, &area);
- farea = (float) area;
- fgets (line_buf, LINE_LEN, fpIn);
- sscanf (line_buf, "%[^=]%c%f%c%[^=]%c%f",
- buf, &equ, &len, &comma, buf, &equ, &width);
-
- if (SAVE_VERT == ON) { /* vertex coord. stored */
- skip_n_lines (fpIn, 4);
- fgets (line_buf, LINE_LEN, fpIn);
- sscanf (line_buf, "%[^:]%c%d", buf, &colon, &n_vertex);
-
- skip_n_lines (fpIn, 1);
- skip_n_lines (fpIn, n_vertex + 1);
- }
- else /* vertex coord not stored */
- skip_n_lines (fpIn, 2);
-
- /* convex hull stats */
- fgets (line_buf, LINE_LEN, fpIn);
- sscanf (line_buf, "%[^=]%c%d", buf, &equ, &h_area);
- fh_area = (float) h_area;
- fgets (line_buf, LINE_LEN, fpIn);
- sscanf (line_buf, "%[^:]%c%c%c%d%c%d%c",
- buf, &colon, &wspace, &opar,
- &x_ctr, &comma, &y_ctr, &cpar);
- /*
- * ** write output
- */
- if (SHOW_INPUT == ON) {
- printf ("%s: %3d %6.0f %8.2f %8.2f %6.0f %f\n",
- line_title, ns, farea, len, width,
- fh_area, farea / fh_area);
- }
-
- switch (MAKE_HIST) {
- case READ_SEGM:
- *(data + i_sgl) = (float) ns;
- break;
- case READ_AREA:
- *(data + i_sgl) = farea;
- break;
- case READ_LEN:
- *(data + i_sgl) = len;
- break;
- case READ_WIDTH:
- *(data + i_sgl) = width;
- break;
- case READ_HAREA:
- *(data + i_sgl) = fh_area;
- break;
- case READ_QUOT:
- *(data + i_sgl) = farea / fh_area;
- break;
- }
- i_sgl++;
- }
- } while (proc_flag != 0);
-
- n_sgl = i_sgl;
- printf ("total no segment clusters in this file: %d\n", n_sgl);
-
- /*
- * ** evaluate statistics
- */
- mean = find_mean (data, n_sgl);
- std_dev = find_sigma (data, n_sgl, mean);
-
- /*
- * ** prepare to evaluate histogram
- */
- #if defined(LINUX)
- qsort (data, n_sgl, sizeof (float), (__compar_fn_t) compare);
- #else
- qsort (data, n_sgl, sizeof (float), compare);
- #endif
-
- #ifdef SHOW_SORT
- printf ("\n...sorted data:\n");
- for (i_sgl = 0; i_sgl < n_sgl; i_sgl++)
- printf (" data[%d] = %f\n", i_sgl, *(data + i_sgl));
- #endif
-
-
- if (MIN_SET == 0)
- min = *(data + 0);
- if (MAX_SET == 0)
- max = *(data + n_sgl - 1);
-
-
- if (MAKE_HIST == READ_SEGM) {
- min = (float) 1.0;
- max = *(data + n_sgl - 1);
- N_BINS = (int) (max - min) + 1;
- }
-
- if ((hist = (float *) calloc ((size_t) N_BINS, sizeof (float))) == NULL) {
- printf ("\nEH_SGL: mem alloc for hist failed\n");
- exit (1);
- }
-
- bin_width = (max - min) / ((float) (N_BINS - 1));
- construct_hist (n_sgl, data, hist, bin_width, min);
-
- printf ("%s\n", HIST_HEADER);
- printf ("......mean: %lf\n", mean);
- printf ("...std_dev: %lf\n", std_dev);
- printf ("...min: %f, bin_width: %f, max: %f\n", min, bin_width, max);
- for (i = 0; i < N_BINS; i++) {
- printf (" %6.2f", *(hist + i));
- if ((i + 1) % 10 == 0)
- printf ("\n");
- }
- fclose (fpIn);
-
- /*
- * ** write output file of type .hdt (see also: .adt, .pdt)
- */
- if (WRITE_FILE == 1) {
- if ((fpOut = fopen (wbuf, "w")) == NULL) {
- printf ("\n...cannot open %s for writing\n",
- wbuf);
- exit (1);
- }
- fprintf (fpOut, "%d\n", N_BINS);
-
- for (i = 0; i < n_parms; i++)
- fprintf (fpOut, "%f\n", foo);
-
- for (i = 0; i < N_BINS; i++)
- fprintf (fpOut, "%f %f\n", (float) i, *(hist + i));
-
- fclose (fpOut);
- }
-
-
- free (hist);
- free (data);
- }
-